package com.dev.toolkit.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dev.toolkit.common.util.JavaCodeGenerateUtil;
import com.dev.toolkit.common.util.StrUtil2;
import com.dev.toolkit.config.ds.DbConnectionInfo;
import com.dev.toolkit.config.ds.DynamicDataSourceUtil;
import com.dev.toolkit.domain.bo.GenerateCodeConfigBO;
import com.dev.toolkit.domain.bo.TableBO;
import com.dev.toolkit.model.EntityPropertyConfig;
import com.dev.toolkit.repository.EntityPropertyConfigMapper;
import com.dev.toolkit.service.IDatabaseConfigService2;
import com.dev.toolkit.service.IEntityPropertyConfigService;
import com.dev.toolkit.service.ITableDataService;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ZhuYouBin
 * @version 1.0.0
 * @date 2024-04-27 21:53:33.082543900
 * @description 实体属性配置表
 */
@Service
public class EntityPropertyConfigService extends ServiceImpl<EntityPropertyConfigMapper, EntityPropertyConfig> implements IEntityPropertyConfigService {
    @Resource
    private ITableDataService tableDataService;
    @Resource
    private IDatabaseConfigService2 databaseConfigService2;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveBatchData(List<TableBO> entityList) {
        if (CollectionUtil.isEmpty(entityList)) {
            return;
        }
        List<EntityPropertyConfig> configList = new ArrayList<>();
        entityList.forEach(ent -> {
            ent.getColumns().forEach(col -> {
                EntityPropertyConfig config = new EntityPropertyConfig();
                config.setName(col.getFiledName());
                config.setPkgName("");
                config.setDataType(col.getFiledType());
                config.setRemark(col.getColumnRemark());
                config.setPinyin(PinyinUtil.getPinyin(config.getName()));
                configList.add(config);
            });
        });
        // 原数据集合中是否存在重复数据
        Set<String> nameSetDistinct = new HashSet<>();
        Iterator<EntityPropertyConfig> it = configList.iterator();
        while (it.hasNext()) {
            EntityPropertyConfig config = it.next();
            if (nameSetDistinct.contains(config.getName())) {
                it.remove();
            } else {
                nameSetDistinct.add(config.getName());
            }
        }

        if (CollectionUtil.isNotEmpty(configList)) {
            // 判断是否重复
            List<List<EntityPropertyConfig>> partitionList = Lists.partition(configList, 1000);
            partitionList.forEach(list -> {
                Set<String> nameSet = list.stream().map(EntityPropertyConfig::getName).collect(Collectors.toSet());
                LambdaQueryWrapper<EntityPropertyConfig> wrapper = Wrappers.lambdaQuery();
                wrapper.in(EntityPropertyConfig::getName, nameSet);
                List<EntityPropertyConfig> originList = this.list(wrapper);
                if (CollectionUtil.isNotEmpty(originList)) {
                    // 剔除已经存在的数据
                    list.removeIf(ent -> originList.stream().anyMatch(data -> data.getName().equals(ent.getName())));
                }
                if (CollectionUtil.isNotEmpty(list)) {
                    this.saveOrUpdateBatch(list, 1000);
                }
            });
        }
    }

    @Override
    public List<EntityPropertyConfig> getEntityPropertyConfigList(String searchParam) {
        LambdaQueryWrapper<EntityPropertyConfig> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StrUtil2.isNotEmpty(searchParam), EntityPropertyConfig::getName, searchParam)
                .or().like(StrUtil2.isNotEmpty(searchParam), EntityPropertyConfig::getPinyin, searchParam)
                .or().like(StrUtil2.isNotEmpty(searchParam), EntityPropertyConfig::getRemark, searchParam);
        wrapper.orderByAsc(EntityPropertyConfig::getName).orderByAsc(EntityPropertyConfig::getPinyin);
        return this.list(wrapper);
    }

    @Override
    public String generateCode(GenerateCodeConfigBO config) {
        return JavaCodeGenerateUtil.generateJavaClass(config);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void synchronizationData(String dsName) {
        new Thread(() -> {
            // 切换数据源
            DbConnectionInfo info = databaseConfigService2.getDbConfigByName(dsName);
            DynamicDataSourceUtil.switchDataSource(dsName, info);
            // 查询数据
            List<TableBO> tableList = tableDataService.getTableList(null, "");
            // 重置数据源
            DynamicDataSourceUtil.resetDataSource();
            this.saveBatchData(tableList);
        }).start();
    }
}